import { Platform, PermissionsAndroid } from 'react-native';
import AsyncStorage from '@react-native-async-storage/async-storage';
import { locationAPI } from '../api';
import { AMAP_KEY } from './amapLocation';
import Geolocation from 'react-native-geolocation-service';
import {
  init,
  Geolocation as AMapGeolocation,
  setLocatingWithReGeocode,
  setGpsFirst,
  setNeedAddress,
  setLocationMode,
  LocationMode,
} from 'react-native-amap-geolocation';
import { AMAP_IOS_KEY, AMAP_ANDROID_KEY } from '@env';

// 高德 SDK 是否已初始化
let isAMapInitialized = false;

/**
 * 初始化高德定位 SDK
 */
export async function initAMapSDK() {
  if (isAMapInitialized) {
    return true;
  }

  try {
    await init({
      ios: AMAP_IOS_KEY || '5ce2265c79345ce6a01f78258884eaad',
      android: AMAP_ANDROID_KEY || '83e7f6f0697bea98a7dfa3557a9ca094',
    });

    // 启用逆地理编码（获取地址信息）- 统一 iOS 和 Android 配置
    setLocatingWithReGeocode(true);

    // Android 特有配置：启用高精度定位
    if (Platform.OS === 'android') {
      // 设置定位模式为高精度（GPS + 网络 + WiFi）
      setLocationMode(LocationMode.Hight_Accuracy);

      // 优先使用GPS定位，提高精度
      setGpsFirst(true);

      // 返回地址信息
      setNeedAddress(true);
    }

    isAMapInitialized = true;
    return true;
  } catch {
    return false;
  }
}

/**
 * 检查是否已有位置权限（不会弹出权限请求）
 * @returns {Promise<boolean>} 是否已有权限
 */
export async function checkLocationPermission() {
  try {
    if (Platform.OS === 'ios') {
      // iOS: 尝试获取位置，如果失败说明没有权限
      // 更可靠的方法是检查之前是否授予过权限
      return new Promise(resolve => {
        Geolocation.getCurrentPosition(
          () => resolve(true),
          error => {
            // 错误代码 1 表示权限被拒绝
            if (error.code === 1) {
              resolve(false);
            } else {
              // 其他错误（如超时）也认为有权限
              resolve(true);
            }
          },
          {
            enableHighAccuracy: false,
            timeout: 1000,
            maximumAge: 100000,
          },
        );
      });
    } else {
      const hasPermission = await PermissionsAndroid.check(
        PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION,
      );
      return hasPermission;
    }
  } catch {
    return false;
  }
}

/**
 * 请求位置权限
 * @returns {Promise<boolean>} 是否获得权限
 */
export async function requestLocationPermission() {
  try {
    let granted = false;
    if (Platform.OS === 'ios') {
      const r = await Geolocation.requestAuthorization('whenInUse');
      granted = r === 'granted';
    } else {
      const r = await PermissionsAndroid.request(
        PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION,
      );
      granted = r === PermissionsAndroid.RESULTS.GRANTED;
    }

    return granted;
  } catch {
    return false;
  }
}

/**
 * 获取当前位置信息（仅使用高德原生定位，返回 GCJ-02 坐标）
 * @param {Object} options 定位选项
 * @returns {Promise<Object>} 位置信息
 */
export async function getCurrentPosition(options = {}) {
  // 确保高德 SDK 已初始化
  await initAMapSDK();

  return new Promise((resolve, reject) => {
    // 设置超时时间（默认5秒，更快的失败响应）
    const timeout = options.timeout || 5000;
    
    const timer = setTimeout(() => {
      reject(new Error('高德定位超时'));
    }, timeout);

    AMapGeolocation.getCurrentPosition(
      position => {
        clearTimeout(timer);
        
        // position 结构：{ coords: {...}, location: {...}, timestamp }
        const { coords, location } = position;

        // 转换为标准格式（兼容原有代码）
        const standardPosition = {
          coords: {
            latitude: coords.latitude,
            longitude: coords.longitude,
            accuracy: coords.accuracy || 0,
            altitude: coords.altitude || 0,
            heading: coords.heading || 0,
            speed: coords.speed || 0,
          },
          timestamp: position.timestamp || Date.now(),
          // 高德额外信息
          amap: {
            address: location?.address,
            city: location?.city,
            cityCode: location?.cityCode,
            district: location?.district,
            province: location?.province,
            street: location?.street,
            poiName: location?.poiName,
            streetNumber: location?.streetNumber,
            locationType: location?.locationType,
            coordinateType: location?.coordinateType,
            coordinateSystem: 'GCJ-02', // 高德坐标系统
            source: 'amap-sdk', // 标记定位来源
          },
        };

        resolve(standardPosition);
      },
      error => {
        clearTimeout(timer);
        console.error('[AMap定位] 定位失败:', error);
        reject(error);
      },
    );
  });
}

/**
 * 通过位置API获取城市信息
 * @param {number} longitude 经度
 * @param {number} latitude 纬度
 * @returns {Promise<Object>} 城市信息
 */
export async function getLocationInfo(longitude, latitude) {
  const resp = await locationAPI.getLocationByLonLat(longitude, latitude);

  const payload = resp?.data?.data || resp?.data || {};
  const apiCity = payload.address?.city || payload.city;
  const apiAdcode = payload.adcode || payload.address?.adcode;

  return {
    city: apiCity,
    adcode: apiAdcode,
    payload,
  };
}

/**
 * 获取城市景点统计信息
 * @param {string} adcode 城市编码
 * @returns {Promise<Object>} 景点统计信息
 */
export async function getCityStatistics(adcode) {
  const countResp = await locationAPI.countByCityCode(adcode);
  const countData = countResp?.data?.data;
  const areasCount = countData?.scenicAreasCount ?? 0;
  const scenicAreasList = countData?.scenicAreasList || [];

  return {
    scenicAreasCount: Number(areasCount) || 0,
    scenicAreasList,
  };
}

/**
 * 检查是否已询问过位置权限
 * @returns {Promise<boolean>} 是否已询问过
 */
export async function hasAskedLocationPermission() {
  const FLAG = 'asked_location_permission';
  const asked = await AsyncStorage.getItem(FLAG);
  return !!asked;
}

/**
 * 标记已询问过位置权限
 * @returns {Promise<void>}
 */
export async function markLocationPermissionAsked() {
  await AsyncStorage.setItem('asked_location_permission', '1');
}

/**
 * 判断坐标是否在中国境外
 */
function isOutOfChina(lat, lon) {
  return lon < 72.004 || lon > 137.8347 || lat < 0.8293 || lat > 55.8271;
}

function transformLat(x, y) {
  let ret =
    -100.0 +
    2.0 * x +
    3.0 * y +
    0.2 * y * y +
    0.1 * x * y +
    0.2 * Math.sqrt(Math.abs(x));
  ret +=
    ((20.0 * Math.sin(6.0 * x * Math.PI) + 20.0 * Math.sin(2.0 * x * Math.PI)) *
      2.0) /
    3.0;
  ret +=
    ((20.0 * Math.sin(y * Math.PI) + 40.0 * Math.sin((y / 3.0) * Math.PI)) *
      2.0) /
    3.0;
  ret +=
    ((160.0 * Math.sin((y / 12.0) * Math.PI) +
      320 * Math.sin((y * Math.PI) / 30.0)) *
      2.0) /
    3.0;
  return ret;
}

function transformLon(x, y) {
  let ret =
    300.0 +
    x +
    2.0 * y +
    0.1 * x * x +
    0.1 * x * y +
    0.1 * Math.sqrt(Math.abs(x));
  ret +=
    ((20.0 * Math.sin(6.0 * x * Math.PI) + 20.0 * Math.sin(2.0 * x * Math.PI)) *
      2.0) /
    3.0;
  ret +=
    ((20.0 * Math.sin(x * Math.PI) + 40.0 * Math.sin((x / 3.0) * Math.PI)) *
      2.0) /
    3.0;
  ret +=
    ((150.0 * Math.sin((x / 12.0) * Math.PI) +
      300.0 * Math.sin((x / 30.0) * Math.PI)) *
      2.0) /
    3.0;
  return ret;
}

/**
 * WGS-84 转 GCJ-02（高德坐标）
 * @param {number} lat WGS-84纬度
 * @param {number} lon WGS-84经度
 * @returns {{ latitude: number, longitude: number }} GCJ-02坐标
 */
export function wgs84ToGcj02(lat, lon) {
  if (isOutOfChina(lat, lon)) {
    return { latitude: lat, longitude: lon };
  }
  const a = 6378245.0;
  // GCJ-02 椭球偏心率平方常数
  const ee = 0.006693421622966;
  let dLat = transformLat(lon - 105.0, lat - 35.0);
  let dLon = transformLon(lon - 105.0, lat - 35.0);
  const radLat = (lat / 180.0) * Math.PI;
  let magic = Math.sin(radLat);
  magic = 1 - ee * magic * magic;
  const sqrtMagic = Math.sqrt(magic);
  dLat = (dLat * 180.0) / (((a * (1 - ee)) / (magic * sqrtMagic)) * Math.PI);
  dLon = (dLon * 180.0) / ((a / sqrtMagic) * Math.cos(radLat) * Math.PI);
  const mgLat = lat + dLat;
  const mgLon = lon + dLon;
  return { latitude: mgLat, longitude: mgLon };
}

/**
 * 使用高德坐标转换服务将 WGS84 坐标转换为 GCJ-02（国测局坐标）
 * 这是解决定位偏差的关键函数
 * @param {number} latitude WGS84 纬度
 * @param {number} longitude WGS84 经度
 * @returns {Promise<{ latitude: number; longitude: number } | null>}
 */
export async function convertWgs84ToGcj02ViaAmap(latitude, longitude) {
  try {
    const url = `https://restapi.amap.com/v3/assistant/coordinate/convert?locations=${longitude},${latitude}&coordsys=gps&key=${AMAP_KEY}`;
    const response = await fetch(url);
    const data = await response.json();

    if (data.status === '1' && data.locations) {
      const [lng, lat] = data.locations.split(',').map(Number);
      if (!Number.isNaN(lat) && !Number.isNaN(lng)) {
        return { latitude: lat, longitude: lng };
      }
    }

    return null;
  } catch {
    return null;
  }
}
